#!/bin/bash

# API测试脚本
# 用于测试RBAC权限控制功能

# 颜色定义
GREEN="\033[0;32m"
YELLOW="\033[1;33m"
BLUE="\033[0;34m"
RED="\033[0;31m"
NC="\033[0m" # No Color

# 打印带颜色的消息
echo_color() {
    echo -e "${1}${2}${NC}"
}

# 检查命令是否存在
check_command() {
    if ! command -v $1 &> /dev/null; then
        echo_color "$RED" "错误: 命令 '$1' 未找到，请先安装。"
        exit 1
    fi
}

# 检查必要的命令
check_command curl
check_command jq

# 设置API基础URL
BASE_URL="http://localhost:5000"

# 保存令牌的变量
ADMIN_TOKEN=""
EDITOR_TOKEN=""
USER_TOKEN=""

# 发送HTTP请求并处理响应
send_request() {
    local method=$1
    local endpoint=$2
    local token=$3
    local data=$4
    
    # 构建curl命令
    local curl_cmd="curl -s -X $method '$BASE_URL$endpoint'"
    
    # 添加认证头（如果提供了令牌）
    if [ -n "$token" ]; then
        curl_cmd="$curl_cmd -H 'Authorization: Bearer $token'"
    fi
    
    # 添加内容类型头和数据（如果提供了数据）
    if [ -n "$data" ]; then
        curl_cmd="$curl_cmd -H 'Content-Type: application/json' -d '$data'"
    fi
    
    # 执行请求并解析响应
    local response=$(eval $curl_cmd)
    local status=$(echo $response | jq -r '.status')
    local message=$(echo $response | jq -r '.message // "无消息"')
    local status_code=$(echo $response | jq -r '.status_code // 200')
    
    # 打印响应信息
    if [ "$status" == "success" ]; then
        echo_color "$GREEN" "[$method $endpoint] 成功: $message"
    else
        echo_color "$RED" "[$method $endpoint] 失败: $message"
    fi
    
    # 返回响应
    echo $response
}

# 登录并获取令牌
login() {
    local username=$1
    local password=$2
    local var_name=$3
    
    echo_color "$BLUE" "=== 登录用户: $username ==="
    
    local data="{\"username\":\"$username\",\"password\":\"$password\"}"
    local response=$(send_request "POST" "/auth/login" "" "$data")
    
    # 提取令牌
    local token=$(echo $response | jq -r '.access_token // ""')
    
    if [ -n "$token" ] && [ "$token" != "null" ]; then
        # 使用eval动态设置变量
        eval $var_name="$token"
        echo_color "$GREEN" "获取令牌成功"
    else
        echo_color "$RED" "获取令牌失败"
    fi
}

# 测试公开API
test_public_api() {
    echo_color "$BLUE" "\n=== 测试公开API ==="
    send_request "GET" "/api/test/public" ""
}

# 测试需要认证的API
test_authenticated_api() {
    echo_color "$BLUE" "\n=== 测试需要认证的API ==="
    
    echo_color "$YELLOW" "无令牌访问（应失败）:"
    send_request "GET" "/api/test/authenticated" ""
    
    echo_color "$YELLOW" "使用普通用户令牌访问:"
    send_request "GET" "/api/test/authenticated" "$USER_TOKEN"
}

# 测试需要管理员权限的API
test_admin_api() {
    echo_color "$BLUE" "\n=== 测试需要管理员权限的API ==="
    
    echo_color "$YELLOW" "使用普通用户令牌访问（应失败）:"
    send_request "GET" "/api/test/admin" "$USER_TOKEN"
    
    echo_color "$YELLOW" "使用编辑者令牌访问（应失败）:"
    send_request "GET" "/api/test/admin" "$EDITOR_TOKEN"
    
    echo_color "$YELLOW" "使用管理员令牌访问:"
    send_request "GET" "/api/test/admin" "$ADMIN_TOKEN"
}

# 测试需要编辑者角色的API
test_editor_api() {
    echo_color "$BLUE" "\n=== 测试需要编辑者角色的API ==="
    
    echo_color "$YELLOW" "使用普通用户令牌访问（应失败）:"
    send_request "GET" "/api/test/editor" "$USER_TOKEN"
    
    echo_color "$YELLOW" "使用编辑者令牌访问:"
    send_request "GET" "/api/test/editor" "$EDITOR_TOKEN"
    
    echo_color "$YELLOW" "使用管理员令牌访问（应成功，因为管理员有所有权限）:"
    send_request "GET" "/api/test/editor" "$ADMIN_TOKEN"
}

# 测试需要特定权限的API
test_permission_api() {
    echo_color "$BLUE" "\n=== 测试需要特定权限的API ==="
    
    echo_color "$YELLOW" "使用普通用户令牌访问（应失败）:"
    send_request "GET" "/api/test/permission" "$USER_TOKEN"
    
    echo_color "$YELLOW" "使用编辑者令牌访问（应成功，因为编辑者有content:publish权限）:"
    send_request "GET" "/api/test/permission" "$EDITOR_TOKEN"
}

# 测试用户管理API
test_user_management() {
    echo_color "$BLUE" "\n=== 测试用户管理API ==="
    
    echo_color "$YELLOW" "获取用户列表（管理员）:"
    send_request "GET" "/api/users" "$ADMIN_TOKEN"
    
    echo_color "$YELLOW" "获取用户列表（普通用户，应成功，因为有user:read权限）:"
    send_request "GET" "/api/users" "$USER_TOKEN"
    
    echo_color "$YELLOW" "获取用户列表（编辑者，应失败，因为没有user:read权限）:"
    send_request "GET" "/api/users" "$EDITOR_TOKEN"
}

# 测试角色管理API
test_role_management() {
    echo_color "$BLUE" "\n=== 测试角色管理API ==="
    
    echo_color "$YELLOW" "获取角色列表（管理员）:"
    send_request "GET" "/api/roles" "$ADMIN_TOKEN"
    
    echo_color "$YELLOW" "创建新角色（管理员）:"
    local data='{"name":"guest","description":"访客角色","permissions":["content:read"]}'
    send_request "POST" "/api/roles" "$ADMIN_TOKEN" "$data"
    
    echo_color "$YELLOW" "创建新角色（普通用户，应失败，因为没有role:create权限）:"
    local data='{"name":"test_role","description":"测试角色"}'
    send_request "POST" "/api/roles" "$USER_TOKEN" "$data"
}

# 测试权限管理API
test_permission_management() {
    echo_color "$BLUE" "\n=== 测试权限管理API ==="
    
    echo_color "$YELLOW" "获取权限列表（管理员）:"
    send_request "GET" "/api/permissions" "$ADMIN_TOKEN"
    
    echo_color "$YELLOW" "创建新权限（管理员）:"
    local data='{"name":"content:archive","resource":"content","action":"archive","description":"归档内容"}'
    send_request "POST" "/api/permissions" "$ADMIN_TOKEN" "$data"
}

# 主函数
main() {
    echo_color "$BLUE" "===== Flask RBAC API 测试脚本 ====="
    echo_color "$YELLOW" "确保应用已经启动并在 $BASE_URL 运行"
    
    # 登录并获取令牌
    login "admin" "admin123" "ADMIN_TOKEN"
    login "editor" "password" "EDITOR_TOKEN"
    login "user" "password" "USER_TOKEN"
    
    # 如果没有获取到管理员令牌，退出测试
    if [ -z "$ADMIN_TOKEN" ]; then
        echo_color "$RED" "无法获取管理员令牌，请确保应用已启动并已初始化数据库"
        exit 1
    fi
    
    # 运行测试
    test_public_api
    test_authenticated_api
    test_admin_api
    test_editor_api
    test_permission_api
    test_user_management
    test_role_management
    test_permission_management
    
    echo_color "$GREEN" "\n===== 测试完成 ====="
}

# 执行主函数
main